package com.rayo.accesscontrollercopy.module.setting.presenter;

import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.Message;

import com.rayo.accesscontrollercopy.R;
import com.rayo.accesscontrollercopy.app.BasePresenter;
import com.rayo.accesscontrollercopy.config.GlobalVariables;
import com.rayo.accesscontrollercopy.model.biz.IParamBiz;
import com.rayo.accesscontrollercopy.model.biz.ParamBiz;
import com.rayo.accesscontrollercopy.model.callback.OnGetDbListener;
import com.rayo.accesscontrollercopy.model.callback.OnUpdateDbListener;
import com.rayo.accesscontrollercopy.model.db.bean.SystemData;
import com.rayo.accesscontrollercopy.model.network.WebSocketHelp;
import com.rayo.accesscontrollercopy.model.service.NetWorkService;
import com.rayo.accesscontrollercopy.model.service.NetworkData;
import com.rayo.accesscontrollercopy.module.setting.view.INetworkView;
import com.rayo.accesscontrollercopy.utils.AppUtils;

import java.io.File;

import static com.rayo.accesscontrollercopy.model.service.NetWorkService.ACTION_NETWORK_API_ERROR;
import static com.rayo.accesscontrollercopy.model.service.NetWorkService.ACTION_NETWORK_DISCONNECT;
import static com.rayo.accesscontrollercopy.model.service.NetWorkService.ACTION_NETWORK_UPDATE_APP;
import static com.rayo.accesscontrollercopy.model.service.NetWorkService.ACTION_NETWORK_UPDATE_DB;


/**
 * Created by yanghaojie on 16/7/25.
 */
public class NetworkPresenter extends BasePresenter {
    private INetworkView iNetworkView;
    private IParamBiz mIParamBiz;
    private boolean bind = false;
    private Context context;

    /**
     * @param context
     * @param iNetworkView
     */
    public NetworkPresenter(Context context, INetworkView iNetworkView) {
        this.context=context;
        this.init(context);
        this.iNetworkView = iNetworkView;
        this.mIParamBiz = new ParamBiz();
        Intent intentNetwork = new Intent(context, NetWorkService.class);
        this.reference.get().bindService(intentNetwork, mNetworkConnection, Context.BIND_AUTO_CREATE);
        this.reference.get().registerReceiver(mNetworkReceiver, makeNetworkUpdateIntentFilter());
    }

    public void onDestroy() {
        if (mNetworkConnection != null && bind)
             this.reference.get().unbindService(mNetworkConnection);
        this.reference.get().unregisterReceiver(mNetworkReceiver);
        removeCallbacksAndMessages(null);
    }

    private static final int LOADING = 0;
    private static final int INIT = 1;
    private static final int SHOW_SNACK_BAR = 2;
    private static final int SHOW_DIALOG = 3;
    private static final int NETWORK_ONLINE = 4;
    private static final int INSTALL = 5;
    private static final int NETWORK_OFFLINE = 6;
    private final BroadcastReceiver mNetworkReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            final NetworkData networkData = (NetworkData) intent.getSerializableExtra(NetWorkService.EXTRA_DATA);
            switch (action) {
                case NetWorkService.ACTION_NETWORK_CONNECT:
                    obtainMessage(NETWORK_ONLINE, true).sendToTarget();
                    iNetworkView.showSnackBar(reference.get().getString(R.string.test_successfully));

                    break;
                case NetWorkService.ACTION_NETWORK_FAILED:
                    obtainMessage(NETWORK_OFFLINE, (int) networkData.getData()).sendToTarget();
                    break;
                case ACTION_NETWORK_UPDATE_DB:
                    obtainMessage(SHOW_SNACK_BAR, reference.get().getString(R.string.setting_save_successfully)).sendToTarget();
                    break;
                case ACTION_NETWORK_API_ERROR:
                    if(networkData.getCmd()==(byte)-1) {
                        if (networkData.getData().equals("The database does not exist.")){
                            obtainMessage(SHOW_SNACK_BAR, reference.get().getString(R.string.db_not)).sendToTarget();
                        }else {
                            obtainMessage(SHOW_SNACK_BAR, reference.get().getString(R.string.test_failed)).sendToTarget();
                        }
                    }
                    else if(networkData.getCmd()==(byte)-2){
                        obtainMessage(SHOW_SNACK_BAR, ( reference.get().getString(R.string.save_download_app_failed))).sendToTarget();
                    }
                    else if(networkData.getCmd()==(byte)-3){
                        obtainMessage(SHOW_SNACK_BAR, reference.get().getString(R.string.no_update)).sendToTarget();
                    }
                    else if(networkData.getCmd()==(byte)-4){
                        obtainMessage(SHOW_SNACK_BAR, reference.get().getString(R.string.port_is_wrong)).sendToTarget();
                    }
                    break;
                case ACTION_NETWORK_DISCONNECT:
                    obtainMessage(SHOW_SNACK_BAR, reference.get().getString(R.string.server_closed)).sendToTarget();
                    break;
                case ACTION_NETWORK_UPDATE_APP:
                    if (null != networkData.getData()) {
                        obtainMessage(INSTALL, networkData.getData()).sendToTarget();
                    }
                    break;
                default:
                    break;
            }
        }
    };

    private final ServiceConnection mNetworkConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            bind = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            bind = false;
        }
    };

    /**
     * @param msg
     */
    @Override
    protected void message(Message msg) {
        switch (msg.what) {
            case LOADING:
                iNetworkView.showProgressBar(true);
                break;
            case INIT:
                iNetworkView.showProgressBar(false);
                SystemData systemData = (SystemData) msg.obj;
                if (null != systemData)
                    iNetworkView.setServerInfo(systemData.getServerIp(), systemData.getServerPort());
                break;
            case SHOW_SNACK_BAR:
                iNetworkView.showProgressBar(false);
                iNetworkView.showSnackBar((String) msg.obj);
                break;
            case SHOW_DIALOG:
                iNetworkView.showProgressBar(false);
                iNetworkView.showAlertDialog((String) msg.obj);
                break;
            case NETWORK_ONLINE:
                iNetworkView.showProgressBar(false);

                iNetworkView.showSnackBar(reference.get().getString(R.string.test_successfully));

                break;
            case NETWORK_OFFLINE:
                iNetworkView.showProgressBar(false);
                int exception = (int) msg.obj;
                if (exception == WebSocketHelp.ConnectException) {
                    iNetworkView.showSnackBar(reference.get().getString(R.string.test_failed));
                } else {
                    iNetworkView.showSnackBar(reference.get().getString(R.string.test_failed));
                }
                break;
            case INSTALL:
                iNetworkView.isInstall((File) msg.obj);
                break;
            default:
                break;
        }
    }

    /**
     *
     */
    @Override
    public void initData() {
        this.mIParamBiz.getNetworkInfo(new OnGetDbListener() {
            @Override
            public <T> void onSuccess(T t) {
                if (SystemData.class.getSimpleName().equals(t.getClass().getSimpleName()))
                    obtainMessage(INIT, t).sendToTarget();
                else
                    obtainMessage(SHOW_DIALOG, reference.get().getString(R.string.data_wrong)).sendToTarget();
            }

            @Override
            public void onFailed(int error) {
                obtainMessage(SHOW_DIALOG, reference.get().getString(R.string.setting_get_failed)).sendToTarget();
            }
        });
    }

    /**
     *
     */
    public void testServer() {
        if (!AppUtils.isNetOk(context)){
            obtainMessage(SHOW_DIALOG, reference.get().getString(R.string.no_internet)).sendToTarget();
            return;
        }
        obtainMessage(LOADING).sendToTarget();
        WebSocketHelp.getmInstance().setmUrl(iNetworkView.getServerIp() + ":" + iNetworkView.getServerPort());
        WebSocketHelp.getmInstance().closeWebsocket(false);
    }


    /**
     *
     */
    public void saveServer() {
        obtainMessage(LOADING).sendToTarget();
        this.mIParamBiz.saveNetworkInfo(iNetworkView.getServerIp(), iNetworkView.getServerPort(), new OnUpdateDbListener() {
            @Override
            public <T> void onSuccess(String action, T t) {
                obtainMessage(SHOW_DIALOG, reference.get().getString(R.string.setting_save_successfully)).sendToTarget();
            }


            @Override
            public void onFailed(String action, String error) {
                obtainMessage(SHOW_DIALOG, reference.get().getString(R.string.setting_save_failed)).sendToTarget();
            }
        });
    }

    /**
     *
     */
    public void updateDb() {
//        obtainMessage(LOADING).sendToTarget();

        if (0 == GlobalVariables.getInstance().getmSiteData().getLockid()) {
            obtainMessage(SHOW_DIALOG, reference.get().getString(R.string.setting_lock_)).sendToTarget();
            return;
        }
        WebSocketHelp.getmInstance().updateDb(String.valueOf(GlobalVariables.getInstance().getmSiteData().getLockid()),false);
//        this.iNetworkBiz.updateDb(String.valueOf(GlobalVariables.getInstance().getmSiteData().getLockid()));
    }

    public void cleanCache() {
        this.mIParamBiz.cleanCache(new OnUpdateDbListener() {
            @Override
            public <T> void onSuccess(String action, T t) {
                obtainMessage(SHOW_DIALOG, reference.get().getString(R.string.setting_clean_successfully)).sendToTarget();
            }

            @Override
            public void onFailed(String action, String error) {
                obtainMessage(SHOW_DIALOG, reference.get().getString(R.string.setting_clean_successfully)).sendToTarget();
            }
        });
    }

    /**
     *
     */
    public void checkUpdate() {
        if (!WebSocketHelp.getmInstance().isConnect()) {
            obtainMessage(SHOW_SNACK_BAR, reference.get().getString(R.string.test_failed)).sendToTarget();
            return;
        }
        obtainMessage(LOADING).sendToTarget();
        WebSocketHelp.getmInstance().updateApp(reference.get());
//        FileUtils.findFile()
//        obtainMessage(SHOW_DIALOG, iParamBiz.getVersion(reference.get())).sendToTarget();
    }

    private static IntentFilter makeNetworkUpdateIntentFilter() {
        final IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(NetWorkService.ACTION_NETWORK_CONNECT);
        intentFilter.addAction(ACTION_NETWORK_DISCONNECT);
        intentFilter.addAction(NetWorkService.ACTION_NETWORK_FAILED);
        intentFilter.addAction(ACTION_NETWORK_UPDATE_DB);
        intentFilter.addAction(ACTION_NETWORK_API_ERROR);
        intentFilter.addAction(ACTION_NETWORK_UPDATE_APP);
        return intentFilter;
    }
}
